﻿using System;
using System.Data;
using System.Data.OleDb;
using System.Text;
using System.Collections.Generic;

namespace HQDBF
{
    /// <summary>
    /// 行情DBF数据访问类
    /// </summary>
    /// <remarks>
    /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
    /// 编写时间：<datetime>2012-10-16 4:40 PM</datetime>
    /// </remarks>
    public class PriceQuery
    {
        private string connSH;
        private string connSZ;

        #region ctor.

        /// <summary>
        /// 创建PriceQuery对象, DBF文件默认地址从.config文件读取
        /// </summary>
        public PriceQuery()
        {
            connSH = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", System.Configuration.ConfigurationManager.AppSettings["Show2003Path"]);
            connSZ = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", System.Configuration.ConfigurationManager.AppSettings["SJSHQPath"]);
        }

        /// <summary>
        /// 创建PriceQuery对象
        /// </summary>
        /// <param name="Path">两个DBF文件所在的地址</param>
        public PriceQuery(string Path)
        {
            connSH = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", Path);
            connSZ = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", Path);
        }

        /// <summary>
        /// 创建PriceQuery对象
        /// </summary>
        /// <param name="Path">两个DBF文件所在的地址</param>
        public PriceQuery(string Show2003Path, string SJSHQPath)
        {
            connSH = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", Show2003Path);
            connSZ = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=dBASE IV;", SJSHQPath);
        }

        #endregion

        #region API

        /// <summary>
        /// 获取单只股票的买入价
        /// </summary>
        /// <param name="code">股票代码</param>
        /// <param name="x">买x</param>
        /// <returns>买入价x</returns>
        public double GetBuyPriceX(string code, int x)
        {
            return GetPriceX(code, x, true);
        }

        /// <summary>
        /// 获取单只股票的卖出价
        /// </summary>
        /// <param name="code">股票代码</param>
        /// <param name="x">卖x</param>
        /// <returns>卖出价x</returns>
        public double GetSellPriceX(string code, int x)
        {
            return GetPriceX(code, x, false);
        }

        /// <summary>
        /// 获取多个卖价x
        /// </summary>
        /// <param name="codes">股票代码数组</param>
        /// <param name="x">卖价x</param>
        /// <returns>结果按代码升序</returns>
        public double[] GetPricesX(string[] codes, int x, bool isBuy)
        {
            double[] result = new double[codes.Length];

            StringBuilder sbSH = new StringBuilder(string.Format("SELECT S1 AS Code, {0} AS Price FROM SHOW2003 WHERE S1 IN ('1'", GetField(true, isBuy, x), x));
            StringBuilder sbSZ = new StringBuilder(string.Format("SELECT HQZQDM AS Code, {0} AS Price FROM SJSHQ WHERE HQZQDM IN ('1'", GetField(false, isBuy, x), x));

            foreach (string code in codes)
            {
                int icode = Convert.ToInt32(code);
                if (icode < 600000)
                {
                    sbSZ.AppendFormat(",'{0}'", code);
                }
                else
                {
                    sbSH.AppendFormat(",'{0}'", code);
                }
            }

            sbSH.Append(")");
            sbSZ.Append(")");

            DataTable dtSH = OleDbHelper.ExecuteDataset(connSH, CommandType.Text, sbSH.ToString()).Tables[0];
            DataTable dtSZ = OleDbHelper.ExecuteDataset(connSZ, CommandType.Text, sbSZ.ToString()).Tables[0];

            dtSH.Merge(dtSZ);

            int i = 0;
            foreach (DataRow row in dtSH.Select("", "Code ASC"))
            {
                result[i] = Convert.ToDouble(row["Price"].ToString());
                i++;
            }

            return result;
        }

        /// <summary>
        /// 开放式查询DataTable
        /// </summary>
        /// <param name="queryString"></param>
        /// <param name="isSHA"></param>
        /// <returns></returns>
        public DataTable OpenQueryTable(string queryString,bool isSHA)
        {
            if (isSHA)
            {
                return OleDbHelper.ExecuteDataset(this.connSH, CommandType.Text, queryString).Tables[0];
            }
            else
            {
                return OleDbHelper.ExecuteDataset(this.connSZ, CommandType.Text, queryString).Tables[0];
            }
        }

        /// <summary>
        /// 开放式查询DataReader
        /// </summary>
        /// <param name="queryString"></param>
        /// <param name="isSHA"></param>
        /// <returns></returns>
        public OleDbDataReader OpenQueryReader(string queryString, bool isSHA)
        {
            if (isSHA)
            {
                return OleDbHelper.ExecuteReader(this.connSH, CommandType.Text, queryString);
            }
            else
            {
                return OleDbHelper.ExecuteReader(this.connSZ, CommandType.Text, queryString);
            }
        }

        #endregion

        #region Privates

        /// <summary>
        /// 获得买/卖价对应的DBF字段
        /// </summary>
        /// <param name="isSH">是否为上海</param>
        /// <param name="isBuy">是否为买</param>
        /// <param name="x"></param>
        /// <returns></returns>
        private string GetField(bool isSH, bool isBuy, int x)
        {
            #region Shanghai

            if (isSH)
            {
                //S9当前买入价、S10当前卖出价、S16申买价二、S18申买价三、
                //S22申卖价二、S24申卖价三、S26申买价四、S28申买价五、S30申卖价四、S32申卖价五

                if (x == 0)
                    return "S8";

                if (isBuy)
                {
                    switch (x)
                    {
                        case 1:
                            return "S9";
                        case 2:
                            return "S16";
                        case 3:
                            return "S18";
                        case 4:
                            return "S26";
                        case 5:
                            return "S28";
                        default:
                            return "S9";
                    }
                }
                else
                {
                    switch (x)
                    {
                        case 1:
                            return "S10";
                        case 2:
                            return "S22";
                        case 3:
                            return "S24";
                        case 4:
                            return "S30";
                        case 5:
                            return "S32";
                        default:
                            return "S10";
                    }
                }
            }

            #endregion

            #region Shenzhen

            else
            {
                if (x == 0)
                    return "HQZJCJ";

                if (isBuy)
                {
                    return "HQBJW" + x.ToString();
                }
                else
                {
                    return "HQSJW" + x.ToString();
                }
            }

            #endregion
        }

        /// <summary>
        /// Gets the price X.
        /// </summary>
        /// <param name="code">The code.</param>
        /// <param name="x">The x.</param>
        /// <param name="isBuy">if set to <c>true</c> [is buy].</param>
        /// <returns></returns>
        /// <remarks>
        /// 代码编写：<author>LANCEZHANG-PC\zhangxl</author><br/>
        /// 编写时间：<datetime>2012-10-16 4:41 PM</datetime>
        /// </remarks>
        private double GetPriceX(string code, int x, bool isBuy)
        {
            OleDbDataReader reader;
            int icode = Convert.ToInt32(code);
            if (icode < 600000)
            {
                string sbSZ = string.Format("SELECT HQZQDM AS Code, {0} AS Price FROM SJSHQ WHERE HQZQDM='{1}'", GetField(false, isBuy, x), code);
                reader = OleDbHelper.ExecuteReader(this.connSZ, CommandType.Text, sbSZ);
            }
            else
            {
                string sbSH = string.Format("SELECT S1 AS Code, {0} AS Price FROM SHOW2003 WHERE S1='{1}'", GetField(true, isBuy, x), code);
                reader = OleDbHelper.ExecuteReader(this.connSH, CommandType.Text, sbSH);
            }

            if (reader.Read())
            {
                double result = reader.GetDouble(1);
                reader.Close();
                reader.Dispose();
                return result;
            }
            else
            {
                throw new Exception("未能找到数据");
            }
        }


        #endregion
    }
}
